package src.application.Doppelkopf;

/**
 * Diese Klasse repraesentiert eine Spielkartefür ein Doppelkopfspiel. Sie
 * besitzt folgende Attribute: int wert: Zahlenwert der
 * Karte(2->Bube,3->Dame,4->König,10->Zehn,11->Ass) char farbe: Character Wert
 * der Kartenfarbe(d->Karo, h->Herz, k->Kreuz, p->Pik) boolean trumpf:
 * Wahrheitswert der angibt ob die Karte Trumpf ist(true) oder nicht(false) int
 * spielart: Zahlenwert, der die Spielart angibt(0->Normalspiel, 1->Bubensolo,
 * 2->Damensolo, 3->Fleischlos, 4->Schweine, 5->Hochzeit, 6->Hochzeit+Schwein)
 *
 * @author Lucksch
 */
public class Karte implements Comparable<Karte> {

    private boolean trumpf;
    private int wert;
    private char farbe;
    private int spielart;

    public Karte(int wert, char farbe) {
        this.wert = wert;
        this.farbe = farbe;
        this.spielart = 0; //wird standartmaessig gesetzt(Normalspiel)
        if (farbe == ('d') || wert == 2 || wert == 3 || wert == 10 && farbe == ('h')) {
            this.trumpf = true;
        } else {
            this.trumpf = false;
        }
    }

    public void setTrumpf(boolean trumpf) {
        this.trumpf = trumpf;
    }

    public char getFarbe() {
        return this.farbe;
    }

    public int getWert() {
        return this.wert;
    }

    public boolean getTrumpf() {
        return this.trumpf;
    }

    public void setSpielart(int spielart) 
    {
        this.spielart = spielart;

        switch (spielart) {
            case 0:
                    if (getFarbe() == ('d') || getWert() == 2 || getWert() == 3
                            || getWert() == 10 && getFarbe() == ('h')) {
                        setTrumpf(true);
                    } else {
                        setTrumpf(false);
                    }
                break;

            case 1:
                    if (getWert() == 2) {
                        setTrumpf(true);
                    } else {
                        setTrumpf(false);
                    }
                break;

            case 2:
                    if (getWert() == 3) {
                        setTrumpf(true);
                    } else {
                        setTrumpf(false);
                    }
                break;

            case 3:
                    setTrumpf(false);
                break;                
            case 4: if (farbe == 'd' && wert == 11) { wert = 12; }
                break;
            case 5: break;
            case 6: if (farbe == 'd' && wert == 11) { wert = 12; }
                break;
            default:
                System.out.println("Fehlerhafte Eingabe");
        }
    }

    public int getSpielart() {
        return spielart;
    }

    public String toString() {
        String s = "Farbe: " + farbe + ", Wert: " + wert + ", Trumpf: " + trumpf;
        return s;
    }

    /**
     * Die Methode weißt jeder Farbe des Typs char einen Integerwert gemaeß
     * ihrer Wertigkeit im Spiel zu. d->0, h->1, p->2, k->3
     *
     * @return farbwert Zahlenwert der Farbe der Karte auf der die Methode
     * aufgerufen wurde
     */
    private int farbeToInt() {
        int farbwert = -1;
        switch (farbe) {
            case 'd':
                farbwert = 0;
                break;
            case 'h':
                farbwert = 1;
                break;
            case 'p':
                farbwert = 2;
                break;
            case 'k':
                farbwert = 3;
                break;
        }
        return farbwert;
    }

    /**
     * Die Methode gibt eine Zahl zurück, die der Wertigkeit der Trumpfkarten
     * entspricht. Der niedrigste Trumpf(KaroKönig) hat dabei den Wert 0. Es
     * wird hochgezaehlt bis zum hoechsten Trumpf, der Herz10, mit dem Wert 11.
     * ACHTUNG: Die Trumpreihenfolge ändert sich wenn als Spielart "Schweine"
     * eingestellt ist! Dann ist das KaroAss hoechster Trumpf mit der Wertigkeit
     * 12.
     *
     * @return trumpfwert
     */
    public int trumpfOrder() {
        int trumpfwert = -10;
        if (trumpf == true) {
            switch (farbe) {
                case 'd':
                    switch (wert) {
                        case 2:
                            trumpfwert = 3;
                            break;
                        case 3:
                            trumpfwert = 7;
                            break;
                        case 4:
                            trumpfwert = 0;
                            break;
                        case 10:
                            trumpfwert = 1;
                            break;
                        case 11:
                            trumpfwert = 2;
                            break;
                        default:
                            System.out.println("Ungueltiger Wert");
                    }
                    break;
                case 'h':
                    switch (wert) {
                        case 2:
                            trumpfwert = 4;
                            break;
                        case 3:
                            trumpfwert = 8;
                            break;
                        case 10:
                            trumpfwert = 11;
                            break;
                        default:
                            System.out.println("Ungueltiger Wert");
                    }
                    break;
                case 'p':
                    switch (wert) {
                        case 2:
                            trumpfwert = 5;
                            break;
                        case 3:
                            trumpfwert = 9;
                            break;
                        default:
                            System.out.println("Ungueltiger Wert");
                    }
                    break;
                case 'k':
                    switch (wert) {
                        case 2:
                            trumpfwert = 6;
                            break;
                        case 3:
                            trumpfwert = 10;
                            break;
                        default:
                            System.out.println("Ungueltiger Wert");
                    }
                    break;
            }
            /*Sonderfall: Schwein(KaroAss wird höchste Trumpf);
             * Fall mit Schweinen gespielt wird, wird Hier nochmal gefragt, ob es sich um ein KaroAss handelt. 
             * Wenn ja wird der trumpfwert noch einmal umgesetzt und  bekommt den Wert 12(hoeher als Herz10). 
             */
            if (spielart == 4 || spielart == 6) {
                if (farbe == 'd' && wert == 11) {
                    trumpfwert = 12;
                }
            }
        } else {
            System.out.println("Karte kein Trumpf");
        }
        return trumpfwert;
    }

    /**
     * Diese Methode weisst Fehlkarten eine Wertigkeit zu und wird dazu
     * gebraucht die Fehlkarten (vor allem auch bei Fleischlos) richtig zu
     * sortieren.
     *
     * @return fehlwert
     */
    private int fehlOrder() {
        int fehlwert = -10;
        if (trumpf == false) {
            switch (farbe) {
                case 'd':
                    if (wert == 2) {
                        fehlwert = 0;
                    } else if (wert == 3) {
                        fehlwert = 1;
                    } else if (wert == 4) {
                        fehlwert = 2;
                    } else if (wert == 10) {
                        fehlwert = 3;
                    } else if (wert == 11) {
                        fehlwert = 4;
                    } else {
                        System.out.println("Ungueltiger Wert");
                    }

                    break;
                case 'h':
                    if (wert == 2) {
                        fehlwert = 5;
                    } else if (wert == 3) {
                        fehlwert = 6;
                    } else if (wert == 4) {
                        fehlwert = 7;
                    } else if (wert == 10) {
                        fehlwert = 8;
                    } else if (wert == 11) {
                        fehlwert = 9;
                    } else {
                        System.out.println("Ungueltiger Wert");
                    }

                    break;

                case 'p':
                    if (wert == 2) {
                        fehlwert = 10;
                    } else if (wert == 3) {
                        fehlwert = 11;
                    } else if (wert == 4) {
                        fehlwert = 12;
                    } else if (wert == 10) {
                        fehlwert = 13;
                    } else if (wert == 11) {
                        fehlwert = 14;
                    } else {
                        System.out.println("Ungueltiger Wert");
                    }

                    break;

                case 'k':
                    if (wert == 2) {
                        fehlwert = 15;
                    } else if (wert == 3) {
                        fehlwert = 16;
                    } else if (wert == 4) {
                        fehlwert = 17;
                    } else if (wert == 10) {
                        fehlwert = 18;
                    } else if (wert == 11) {
                        fehlwert = 19;
                    } else {
                        System.out.println("Ungueltiger Wert");
                    }

                    break;
            }

        } else {
            System.out.println("Karte kein Fehl!");
        }
        return fehlwert;
    }

    /**
     * Vergleicht die aktuelle Karte mit der uebergebenen und gibt einen
     * Zahlenwert für die hoehere Karte zurueck. Da das Interface Comparable
     * implementiert wurde Es wird nach den unterschiedlichen Spielarten
     * unterschieden.
     *
     * @param k Uebergebene Karte mit der die aktuelle Karte verglichen wird.
     * @return -1 falls die uebergebene Karte k "groeßer"(hoeherwertig) ist als
     * die Aktuelle, 1 falls die aktuelle Karte "groeßer" ist als die
     * Uebergebene. (gleich kommt nicht vor, da immer eine Karte die hoehere
     * sein muss und bei gleichen Karten die zuerst gespielte gewinnt).
     */
    public int compareStichkarten(Karte k) {

        switch (spielart) {
            case 0://Normalspiel
                if (this.trumpf == false & k.getTrumpf() == false && this.farbe == k.getFarbe() && this.wert < k.getWert()
                        || //beides kein Trumpf; gleiche Farbe; wert der übergeb Karte ist höher als akt Karte
                        this.trumpf == false && k.getTrumpf() == true
                        || // akt Karte kein Trumpf, uebergeb Karte Trumpf
                        this.trumpf == true && k.getTrumpf() == true && this.trumpfOrder() < k.trumpfOrder()) //beides Trumpf; Trumpfwert der uebergeb Karte hoeher(zB pik Dame hoeher als karo 10)
                {
                    return -1;
                } else {
                    return 1;
                }


            case 1: //Bubensolo
            case 2: //Damensolo
                if ((trumpf == true && k.getTrumpf() == true && this.farbeToInt() < k.farbeToInt())
                        || trumpf == false && k.getTrumpf() == true || trumpf == false && k.getTrumpf() == false && farbe == k.getFarbe() && wert < k.getWert()) {
                    //übergebene Karte ist höher, falls es ein höhere/r Dame/Bube ist oder es ein/e Bube/Dame ist
                    //und die akt. Karte keine/r oder beides keine Buben/Damen sind und die übergebene Karte einen höheren Wert hat
                    return -1;
                } else {
                    return 1;
                }

            case 3: //Fleischlos, kein Trumpf
                if (farbe == k.getFarbe() && wert < k.getWert()) {
                    return -1;
                } else {
                    return 1; // in allen anderen Fällen ist die übergebene Karte weniger wert,
                    // da entweder andere Farbe oder gleiche Farbe und kleinerer od gleicher Wert
                }

            default:
                System.out.println("Fehlerhafte Eingabe!");
                return -10;
        }
    }

    //compareTo() Methode um die Handkarten zu sortieren
    /**
     * Karte implementiert das Interface Comparable und mit dieser Methode ist
     * es möglich, ein Array mit Karten automatisch sortieren zu lassen. Dies
     * wird u.a. zur Darstellung der geordneten Handkarten benoetigt.
     *
     * @param k Uebergebene Karte mit der die aktuelle Karte verglichen wird
     * @return -1 falls die uebergebene Karten groesser ist; 1 falls die
     * aktuelle Karte groesser ist; -10 bei Fehlerfall
     */
    public int compareTo(Karte k) {
        switch (spielart) {
            case 0://Normalspiel
                if ((this.trumpf == false && k.getTrumpf() == true)
                        || this.trumpf == true && k.getTrumpf() == true && k.trumpfOrder() > this.trumpfOrder()
                        || this.trumpf == false && k.getTrumpf() == false && k.fehlOrder() > this.fehlOrder()) {

                    return -1; //uebergebene Karte k ist groesser  
                } else {
                    return 1;
                }

            case 1:
            case 2://Bubensolo, Damensolo
                if (this.trumpf == false && k.getTrumpf() == false && k.fehlOrder() > this.fehlOrder()
                        || this.trumpf == false && k.getTrumpf() == true
                        || this.trumpf == true && k.getTrumpf() == true && k.farbeToInt() > this.farbeToInt()) {
                    return -1;
                } else {
                    return 1;
                }

            case 4://Fleischlos
                if (k.fehlOrder() > this.fehlOrder()) {
                    return -1;
                } else {
                    return 1;
                }

            default:
                System.out.println("Fehlerhafte Eingabe");
                return -10;
        }
    }
}
